//
// Created by TheMorbidArk on 2022/11/6.
//

#ifndef VANTIDEL_CPP_OBJFN_H
#define VANTIDEL_CPP_OBJFN_H

#include "utils.h"
#include "ObjMeta.h"

class ObjThread;

#define INITIAL_FRAME_NUM 4

typedef struct {
    char *fnName;     //函数名
    IntBuffer lineNo; //行号
} FnDebug;   //在函数中的调试结构

class ObjFn {
public:
    ObjHeader objHeader;
    ByteBuffer instrStream{};  //函数编译后的指令流
    ValueBuffer constants{};   // 函数中的常量表

    ObjModule *module = nullptr;    //本函数所属的模块

    //本函数最多需要的栈空间,是栈使用空间的峰值
    uint32_t maxStackSlotUsedNum = 0;
    uint32_t upvalueNum = 0;      //本函数所涵盖的upvalue数量
    uint8_t argNum = 0;   //函数期望的参数个数
#if DEBUG
    FnDebug* debug;
#endif

    ObjFn(VM *vm, ObjModule *objModule, uint32_t slotNum);

    ObjFn *NewObjFn(VM *vm, ObjModule *objModule, uint32_t slotNum);

};

class ObjUpvalue {
public:
    ObjHeader objHeader;

    //栈是个Value类型的数组,localVarPtr指向upvalue所关联的局部变量
    Value *localVarPtr;

    //已被关闭的upvalue
    Value closedUpvalue;

    ObjUpvalue *next;   //用以链接openUpvalue链表

    ObjUpvalue(VM *vm, Value *localVarPtr);

    ObjUpvalue *NewObjUpvalue(VM *vm, Value *localVarPtr);

    static void CloseUpvalue(ObjThread *objThread, Value *lastSlot);

    static ObjUpvalue *CreateOpenUpvalue(VM *vm, ObjThread *objThread, Value *localVarPtr);
};

class ObjClosure {
public:
    ObjHeader objHeader;
    ObjFn *fn;   //闭包中所要引用的函数

    ObjUpvalue *upvalues[0]; //用于存储此函数的 "close upvalue"

    ObjClosure(VM *vm, ObjFn *objFn);

    ObjClosure *NewObjClosure(VM *vm, ObjFn *objFn);
};

typedef struct {
    uint8_t *ip;    //程序计数器 指向下一个将被执行的指令

    //在本frame中执行的闭包函数
    ObjClosure *closure;

    //frame是共享therad.stack
    //此项用于指向本frame所在thread运行时栈的起始地址
    Value *stackStart;
} Frame;  //调用框架

inline static void CreateFrame(VM *vm, ObjThread *objThread, ObjClosure *objClosure, int argNum);

#endif //VANTIDEL_CPP_OBJFN_H
